<?php
/**
 * Imgur.com API-based image upload class.
 *
 * @author Lei Lee
 * @version 1.0
 */
class ImgurApi {
	/**
	 * Pictures from other Internet sites.
	 *
	 */
	const UPLOAD_FROM_URL = 1;
	
	/**
	 * Photos from the local computer hard disk.
	 *
	 */
	const UPLOAD_FROM_LOCAL = 2;
	
	/**
	 * WebClient object instance.
	 *
	 * @var WebClient
	 */
	private $http = NULL;
	
	/**
	 * Cookie dynamically generated file name.
	 *
	 * @var string
	 */
	private $cookie_jar_file = NULL;
	
	/**
	 * Set Cookie file directory.
	 *
	 * @var string
	 */
	private $cookie_dir = NULL;
	
	/**
	 * Set the login account name.
	 *
	 * @var string
	 */
	private $username = NULL;
	
	/**
	 * Set login password.
	 *
	 * @var string
	 */
	private $password = NULL;
	
	/**
	 * Set the image source model. (1, Other Internet sites | 2, Local upload)
	 *
	 * @var boolean
	 */
	private $mode = 1;
	
	/**
	 * Sets a string tag.
	 * Note: The method used to generate the MD5 Cookie file name.
	 *
	 * @var string
	 */
	private $sign_key = NULL;
	
	/**
	 * Set Debug mode.
	 *
	 * @var boolean
	 */
	private $debug = false;
	
	/**
	 * Constructor.
	 *
	 */
	function __construct() {
	}
	
	/**
	 * Send pictures to imgur.com server.
	 *
	 * @param mixed $data
	 * @param string $name
	 * @param string $title
	 * @param string $caption
	 */
	function send($data, $name = NULL, $title = NULL, $caption = NULL) {
		if (is_null( $this->username ))
			throw new ImgurApiArgumentsException( '(imgur.com) Your account name isn\'t set.', -1 );
		if (is_null( $this->password ))
			throw new ImgurApiArgumentsException( '(imgur.com) Your password isn\'t set.', -1 );
		if (is_null( $this->sign_key ))
			throw new ImgurApiArgumentsException( 'Be sure to set a unique identification string, it will serve as Cookie file name Hash value.', -1 );
			
		// Check Cookie storage directory exists?
		// If not exist, the direct use of the system temporary directory to store Cookie data files.
		if (is_null( $this->cookie_dir ))
			$this->cookie_dir = sys_get_temp_dir();
		
		$this->cookie_jar_file = rtrim( $this->cookie_dir, '/\\' ) . DIRECTORY_SEPARATOR . md5( date( 'Ymd' ) . $this->sign_key );
		
		// If the Cookie data file does not exist, then the method call log and create a temporary Cookie data files ...
		if (!(file_exists( $this->cookie_jar_file ) && is_file( $this->cookie_jar_file )))
			$this->login();
		
		if ($this->mode == 1) {
			$sResult = $this->http->send( 'http://api.imgur.com/2/upload.json', true, array(
				'image' => $data, 
				'name' => $name, 
				'title' => $title, 
				'caption' => $caption
			), true, $this->cookie_jar_file, 120, false );
		}
		
		$d = json_decode( $sResult, true );
		
		if (is_array( $d )) {
			if ($this->debug) {
				$d['debug'] = array(
					'cookie_jar_file' => $this->cookie_jar_file, 
					'cookie_dir' => $this->cookie_dir, 
					'sign_key' => $this->sign_key
				);
			}
			if (isset( $d['error'] ))
				return false;
			else
				return $d['upload'];
		} else {
			throw new ImgurApiDataParserException( 'Remote call returns the wrong format.', -1 );
		}
	}
	
	/**
	 * Set Cookie store directory.
	 *
	 * @param string $cookie_dir
	 * @return ImgurApi
	 */
	function setCookieDirectory($cookie_dir) {
		$this->cookie_dir = $cookie_dir;
		return $this;
	}
	
	/**
	 * Set the login user name.
	 *
	 * @param string $username
	 * @return ImgurApi
	 */
	function setUsername($username) {
		$this->username = $username;
		return $this;
	}
	
	/**
	 * Set login password.
	 *
	 * @param string $password
	 * @return ImgurApi
	 */
	function setPassword($password) {
		$this->password = $password;
		return $this;
	}
	
	/**
	 * Set the string identifies the Key field.
	 *
	 * @param string $sign_key
	 * @return ImgurApi
	 */
	function setKey($sign_key) {
		$this->sign_key = $sign_key;
		return $this;
	}
	
	/**
	 * Set WebClient object instance.
	 *
	 * @param WebClient $http
	 * @return ImgurApi
	 */
	function setHttp(&$http) {
		$this->http = &$http;
		return $this;
	}
	
	/**
	 * Set Debug on / off state.
	 *
	 * @param boolean $debug
	 * @return ImgurApi
	 */
	function debug($debug) {
		$this->debug = $debug;
		return $this;
	}
	
	/**
	 * For instance a static object.
	 *
	 * @param WebClient $http
	 * @return ImgurApi
	 */
	static function getInstance(&$http) {
		return new ImgurApi( $http );
	}
	
	/**
	 * Cookie Login imgur.com site and create a data file.
	 *
	 * @param string $username
	 * @param string $password
	 * @throws ImgurApiLoginException
	 */
	private function login() {
		try {
			$this->http->send( 'http://api.imgur.com/2/signin', true, array(
				'username' => $this->username, 
				'password' => $this->password
			), false, $this->cookie_jar_file, 30, false );
		} catch ( Exception $ex ) {
			throw new ImgurApiLoginException( $ex->getMessage(), $ex->getCode() );
		}
	}
}

class ImgurApiArgumentsException extends Exception {
}
class ImgurApiLoginException extends Exception {
}
class ImgurApiDataParserException extends Exception {
}